"""
CREATE TABLE `datas` (
  `cid` int(11) NOT NULL AUTO_INCREMENT,
  `uid` varchar(50) DEFAULT NULL,
  `timestamp` bigint(20) DEFAULT NULL,
  `isreal` tinyint(1) DEFAULT NULL,
  `iscomplete` tinyint(1) DEFAULT NULL,
  `ttl_class` double DEFAULT NULL,
  `ttl_drinking` double DEFAULT NULL,
  `ttl_eating` double DEFAULT NULL,
  `ttl_exercising` double DEFAULT NULL,
  `ttl_misc` double DEFAULT NULL,
  `ttl_sleeping` double DEFAULT NULL,
  `ttl_socializing` double DEFAULT NULL,
  `ttl_spiritual` double DEFAULT NULL,
  `ttl_studying` double DEFAULT NULL,
  `ttl_work` double DEFAULT NULL,
  `avg_nightly_sleep_weekday` double,
  `avg_nightly_sleep_weekend` double,
  `days_drank` tinyint,
  `avg_daily_meals` double,
  `days_exercised` tinyint,
  PRIMARY KEY (`cid`)
) AUTO_INCREMENT=0;

"""


import time
import sqlalchemy
from   sqlalchemy import Column, Integer, String, create_engine
from   sqlalchemy.types import Float
from   sqlalchemy.ext.declarative import declarative_base
from   sqlalchemy.orm import sessionmaker

def getNightSleep(day0, day1, timeblocks):
    """ 
    Finds the last block of sleep in day0 (and it must be in the evening),
    the first block of sleep in day1 (and it must be in the morning),
    and returns the sum of their durations.
    """
    night = filter(lambda tb: tb['day'] == day0 and tb['activity'] == 'sleeping' and tb['hour'] >= 12,
                   timeblocks)
    morning = filter(lambda tb: tb['day'] == day1 and tb['activity'] == 'sleeping' and tb['hour'] < 12,
                     timeblocks)
    return (night[-1]['duration'] if night else 0) + (morning[0]['duration'] if morning else 0)


def getNumDays(activity, timeblocks):
    """ Adds up the days that a specific activity occurs within the list of timeblocks, for a max of 7 days. """
    freq = 0
    for i in range(7):
        for tb in filter(lambda tb: tb['day'] == i, timeblocks):
            if tb['activity'] == activity:
                freq += 1
                break
    return freq


def getDailyAvg(activity, timeblocks):
    """ Returns the daily average occurrence of 'activity'  """
    return len(filter(lambda tb: tb['activity'] == activity, timeblocks)) / 7
    

class Datas(declarative_base()):
    """
    Represents various datas entered into thee "Datas" table.
    """
    
    __tablename__ = "datas"

    cid           = Column(Integer, primary_key=True)
    uid           = Column(String)
    timestamp     = Column(Integer)
    isreal        = Column(Integer)
    iscomplete    = Column(Integer)
    ttl_class          = Column(Float)
    ttl_drinking       = Column(Float)
    ttl_eating         = Column(Float)
    ttl_exercising     = Column(Float)
    ttl_misc           = Column(Float)
    ttl_sleeping       = Column(Float)
    ttl_socializing    = Column(Float)
    ttl_spiritual      = Column(Float)
    ttl_studying       = Column(Float)
    ttl_work           = Column(Float)
    avg_nightly_sleep_weekday = Column(Float)
    avg_nightly_sleep_weekend = Column(Float)
    days_drank                = Column(Float)
    avg_daily_meals           = Column(Float)
    days_exercised            = Column(Float)

    def __init__(self, timeblocks, uid = None, isreal = True):
        timestamp = time.time()        
        self.uid = str(timestamp) if uid == None else uid
        self.timestamp = int(timestamp)
        self.isreal = isreal
        
        totals = {
            "class":0.0,
            "drinking":0.0,
            "eating":0.0,
            "exercising":0.0,
            "miscellaneous":0.0,
            "sleeping":0.0,
            "socializing":0.0,
            "spiritual":0.0,
            "studying":0.0,
            "work":0.0,
            }
        
        daysFilled = [False,False,False,False,False,False,False]
        for tb in timeblocks:
            daysFilled[tb['day']] = True 
            totals[tb['activity']] += tb['duration']
        
        self.iscomplete = False not in daysFilled
        
        self.ttl_class       = totals['class']
        self.ttl_drinking    = totals['drinking']
        self.ttl_eating      = totals['eating']
        self.ttl_exercising  = totals['exercising']
        self.ttl_misc        = totals['miscellaneous']
        self.ttl_sleeping    = totals['sleeping']
        self.ttl_socializing = totals['socializing']
        self.ttl_spiritual   = totals['spiritual']
        self.ttl_studying    = totals['studying']
        self.ttl_work        = totals['work']
        self.avg_nightly_sleep_weekday = (
            sum([ getNightSleep(0,1,timeblocks),
                  getNightSleep(1,2,timeblocks),
                  getNightSleep(2,3,timeblocks),
                  getNightSleep(3,4,timeblocks),
                  getNightSleep(4,5,timeblocks) ])/5
            )
        self.avg_nightly_sleep_weekend = (
            sum([ getNightSleep(5,6,timeblocks),
                  getNightSleep(6,0,timeblocks) ])/2
            )
        self.days_drank = getNumDays('drinking', timeblocks)
        self.days_exercised = getNumDays('exercising', timeblocks)
        self.avg_daily_meals = getDailyAvg('eating', timeblocks)
